home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
infor
/
tsptp.zip
/
DHRY.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-04-09
|
25KB
|
574 lines
(******************************************************************************)
(* *)
(* "DHRYSTONE" Benchmark Program *)
(* ----------------------------- *)
(* *)
(* Version: Pascal/ 2 (Measurement Version, for MS-DOS in one file) *)
(* *)
(* File: Dhry.mod *)
(* *)
(* Date: Apr. 1990 *)
(* *)
(* Author: Reinhold P. Weicker *)
(* (Translated from the C & Pascal versions by P.S. Wilson) *)
(* *)
(******************************************************************************)
(* *)
(* The following program contains statements of a high level programming *)
(* language (here: Pascal) in a distribution considered representative: *)
(* *)
(* assignments 52 (55.3 %) *)
(* control statements 24 (25.5 %) *)
(* procedure, function calls 18 (19.1 %) *)
(* *)
(* 102 statements are dynamically executed. The program is balanced with *)
(* respect to the three aspects: *)
(* *)
(* - statement type *)
(* - operand type *)
(* - operand locality *)
(* operand global, local, parameter, or constant. *)
(* *)
(* The combination of these three aspects is balanced only approximately. *)
(* *)
(* 1. Statement Type: *)
(* ----------------- number *)
(* *)
(* V1 := V2 9 *)
(* (incl. V1 := F(..) *)
(* V := Constant 12 *)
(* Assignment, 7 *)
(* with array element *)
(* Assignment, 6 *)
(* with record component *)
(* -- *)
(* 34 34 *)
(* *)
(* X := Y +|-|AND|OR Z 5 *)
(* X := Y +|-|= Constant 6 *)
(* X := X +|- 1 3 *)
(* X := Y *|DIV Z 2 *)
(* X := Expression, 1 *)
(* two operators *)
(* X := Expression, 1 *)
(* three operators *)
(* -- *)
(* 18 18 *)
(* *)
(* IF .... 12 *)
(* with "ELSE" 6 *)
(* without "ELSE" 6 *)
(* executed 2 *)
(* not executed 4 *)
(* FOR ... 6 | counted every time *)
(* WHILE ... 4 | the loop condition *)
(* REPEAT ... UNTIL 1 | is evaluated *)
(* CASE ... 1 *)
(* *)
(* -- *)
(* 24 24 *)
(* *)
(* P (...) procedure call 12 *)
(* user procedure 10 *)
(* library procedure 2 *)
(* X := F (...) *)
(* function call 6 *)
(* user function 5 *)
(* library function 1 *)
(* -- *)
(* 18 18 *)
(* --- *)
(* 94 *)
(* *)
(* The average number of parameters in procedure or function calls *)
(* is 1.82 (not counting the function values as implicit parameters). *)
(* *)
(* *)
(* 2. Operators *)
(* ------------ *)
(* number approximate *)
(* percentage *)
(* *)
(* Arithmetic 31 50.8 *)
(* *)
(* + 20 32.8 *)
(* - 7 11.5 *)
(* * 3 4.9 *)
(* DIV (int div) 1 1.6 *)
(* *)
(* Comparison 26 42.6 *)
(* *)
(* = 9 14.8 *)
(* # 4 6.6 *)
(* > 1 1.6 *)
(* < 3 4.9 *)
(* >= 1 1.6 *)
(* <= 8 13.1 *)
(* *)
(* Logic 4 6.6 *)
(* *)
(* AND 1 1.6 *)
(* OR 1 1.6 *)
(* NOT 2 3.3 *)
(* *)
(* -- ----- *)
(* 61 100.0 *)
(* *)
(* *)
(* 3. Operand Type (counted once per operand reference): *)
(* --------------- *)
(* number approximate *)
(* percentage *)
(* *)
(* Integer 171 71.8 % *)
(* Character 45 18.9 % *)
(* Pointer 12 5.0 % *)
(* String30 6 2.5 % *)
(* Array 2 0.8 % *)
(* Record 2 0.8 % *)
(* --- ------- *)
(* 238 99.8 % *)
(* *)
(* When there is an access path leading to the final operand (e.g. a record *)
(* component), only the final data type on the access path is counted. *)
(* *)
(* *)
(* 4. Operand Locality: *)
(* ------------------- *)
(* number approximate *)
(* percentage *)
(* *)
(* local variable 111 46.6 % *)
(* global variable 21 8.8 % *)
(* parameter 45 18.9 % *)
(* value 23 9.7 % *)
(* reference 22 9.2 % *)
(* function result 6 2.5 % *)
(* constant 55 23.1 % *)
(* --- ------- *)
(* 238 99.9 % *)
(* *)
(* *)
(* The program does not compute anything meaningful, but it is syntactically *)
(* and semantically correct. All variables have a value assigned to them *)
(* before they are used as a source operand. *)
(* *)
(* There may be cases where a highly optimizing compiler may recognize *)
(* unnecessary statements and may not generate code for them. *)
(* *)
(* There has been no explicit effort to account for the effects of a *)
(* cache, or to balance the use of long or short displacements for code or *)
(* data. *)
(* *)
(******************************************************************************)
PROGRAM Dhry(Output);
(******************************************************************************)
(* TIMING *)
(******************************************************************************)
(*$IFNDEF TopSpeed *)
(*%F TRUE *** Compile for Turbo Pascal ***)
USES TPBench;
(*%E*)
(*$ELSE *** Compile for TopSpeed Pascal ***)
IMPORT TSBench *;
(*$ENDIF *)
(******************************************************************************)
(* Global type definitions *)
TYPE
Enumeration = (Ident_1, Ident_2, Ident_3, Ident_4, Ident_5);
One_To_Thirty = 1..30;
One_To_Fifty = 1..50;
Capital_Letter = 'A'..'Z';
Str30 = ARRAY [One_To_Thirty] OF CHAR;
Array1DimInt = ARRAY [One_To_Fifty] OF BmInt;
Array2DimInt = ARRAY [One_To_Fifty, One_To_Fifty] OF BmInt;
Record_Pointer = ^Record_Type;
Record_Type = RECORD
Pointer_Comp: Record_Pointer;
CASE Discr: Enumeration OF
Ident_1:
( Enum_Comp: Enumeration;
Int_Comp: One_To_Fifty;
String_Comp: Str30
);
Ident_2:
( Enum_Comp_2: Enumeration;
String_Comp_2: Str30
);
Ident_3, Ident_4, Ident_5:
( Char_Comp_1,
Char_Comp_2: CHAR
);
END;
(* Global Variables *)
VAR
Pointer_Glob,
Next_Pointer_Glob: Record_Pointer;
Int_Glob: BmInt;
Bool_Glob: BOOLEAN;
Char_Glob_1,
Char_Glob_2: CHAR;
Array_Glob_1: Array1DimInt;
Array_Glob_2: Array2DimInt;
FUNCTION Func_1 (Char_Par_1_Val, Char_Par_2_Val: Capital_Letter): Enumeration;
(**************)
(* executed three times *)
(* first call: Char_Par_1_Val == 'H', Char_Par_2_Val == 'R' *)
(* second call: Char_Par_1_Val == 'A', Char_Par_2_Val == 'C' *)
(* third call: Char_Par_1_Val == 'B', Char_Par_2_Val == 'C' *)
VAR
Char_Loc_1, Char_Loc_2: Capital_Letter;
BEGIN
Char_Loc_1 := Char_Par_1_Val;
Char_Loc_2 := Char_Loc_1;
IF (Char_Loc_2 <> Char_Par_2_Val)
THEN (* executed *)
Func_1 := Ident_1
ELSE (* not executed *)
Func_1 := Ident_2;
END;
FUNCTION Func_2 (String_Par_1_Ref, String_Par_2_Ref: Str30): BOOLEAN;
(**************)
(* executed once *)
(* String_Par_1_Ref = 'DHRYSTONE PROGRAM, 1'ST STRING' *)
(* String_Par_2_Ref = 'DHRYSTONE PROGRAM, 2'ND STRING' *)
VAR
Int_Loc: One_To_Thirty;
Char_Loc: Capital_Letter;
BEGIN
Int_Loc := 2;
WHILE (Int_Loc <= 2) DO (* loop body executed once *)
BEGIN
IF Func_1(String_Par_1_Ref[Int_Loc], String_Par_2_Ref[Int_Loc+1]) = Ident_1 THEN
BEGIN (* executed *)
Char_Loc := 'A';
Int_Loc := Int_Loc + 1;
END (* IF *)
END; (* WHILE *)
IF (Char_Loc >= 'W') AND (Char_Loc < 'Z')
THEN (* not executed *)
Int_Loc := 7;
IF Char_Loc = 'X'
THEN (* not executed *)
Func_2 := TRUE
ELSE (* executed *)
BEGIN
IF String_Par_1_Ref = String_Par_2_Ref THEN
BEGIN (* not executed *)
Int_Loc := Int_Loc + 7;
Func_2 := TRUE
END ELSE (* executed *)
BEGIN
Func_2 := FALSE
END (* IF String_Par_1 > String_Par_2 *)
END (* IF Char_Loc *)
END;
FUNCTION Func_3 (Enum_Par_Val: Enumeration): BOOLEAN;
(**************)
(* executed once *)
(* Enum_Par_Val == Ident_3 *)
VAR
Enum_Loc: Enumeration;
BEGIN
Enum_Loc := Enum_Par_Val;
IF Enum_Loc = Ident_3 THEN
BEGIN (* executed *)
Func_3 := TRUE
END;
Func_3 := FALSE
END;
PROCEDURE Proc_8 (Array_Par_1_Ref: Array1DimInt; Array_Par_2_Ref: Array2DimInt;
Int_Par_Val_1, Int_Par_Val_2: BmInt);
(**************)
(* executed once *)
(* Int_Par_Val_1 = 3 *)
(* Int_Par_Val_2 = 7 *)
VAR
Int_Index, Int_Loc: One_To_Fifty;
BEGIN
Int_Loc := Int_Par_Val_1 + 5;
Array_Par_1_Ref [Int_Loc] := Int_Par_Val_2;
Array_Par_1_Ref [Int_Loc+1] := Array_Par_1_Ref [Int_Loc];
Array_Par_1_Ref [Int_Loc+30] := Int_Loc;
FOR Int_Index := Int_Loc TO Int_Loc+1 DO (* loop twice *)
Array_Par_2_Ref [Int_Loc] [Int_Index] := Int_Loc;
Array_Par_2_Ref [Int_Loc] [Int_Loc-1] := Array_Par_2_Ref [Int_Loc] [Int_Loc-1] + 1;
Array_Par_2_Ref [Int_Loc+20] [Int_Loc] := Array_Par_1_Ref [Int_Loc];
Int_Glob := 5
END;
PROCEDURE Proc_7 (Int_Par_Val1, Int_Par_Val2: One_To_Fifty;
VAR Int_Par_Ref: One_To_Fifty);
(**************)
(* executed three times *)
(* first call: Int_Par_Val1 = 2, Int_Par_Val2 = 3, *)
(* Int_Par_Ref becomes 7 *)
(* second call: Int_Par_Val1 = 6, Int_Par_Val2 = 10, *)
(* Int_Par_Ref becomes 18 *)
(* third call: Int_Par_Val1 = 10, Int_Par_Val2 = 5, *)
(* Int_Par_Ref becomes 17 *)
VAR
Int_Loc: One_To_Fifty;
BEGIN
Int_Loc := Int_Par_Val1 + 2;
Int_Par_Ref := Int_Par_Val2 + Int_Loc
END;
PROCEDURE Proc_6 (Enum_Par_Val: Enumeration; VAR Enum_Par_Ref: Enumeration);
(**************)
(* executed once *)
(* Enum_Par_Val = Ident_3, Enum_Par_Ref becomes Ident_2 *)
BEGIN
Enum_Par_Ref := Enum_Par_Val;
IF NOT Func_3 (Enum_Par_Val)
THEN (* not executed *)
Enum_Par_Ref := Ident_4;
CASE Enum_Par_Val OF
Ident_1:
Enum_Par_Ref := Ident_1;
Ident_2:
IF Int_Glob > 100
THEN
Enum_Par_Ref := Ident_1
ELSE
Enum_Par_Ref := Ident_4;
Ident_3: (* executed *)
Enum_Par_Ref := Ident_2;
Ident_4, Ident_5:
Enum_Par_Ref := Ident_3;
END (* case *)
END;
PROCEDURE Proc_5; (* without parameters *)
(**************)
(* executed once *)
BEGIN
Char_Glob_1 := 'A';
Bool_Glob := FALSE
END;
PROCEDURE Proc_4; (* without parameters *)
(**************)
(* executed once *)
VAR
Bool_Loc: BOOLEAN;
BEGIN
Bool_Loc := (Char_Glob_1 = 'A');
Bool_Loc := (Bool_Loc OR Bool_Glob);
Char_Glob_2 := 'B'
END;
PROCEDURE Proc_3 (VAR Pointer_Par_Ref: Record_Pointer);
(**************)
(* executed once *)
(* Pointer_Par_Ref becomes Pointer_Glob *)
BEGIN
IF Pointer_Glob <> NIL
THEN (* executed *)
Pointer_Par_Ref := Pointer_Glob^.Pointer_Comp
ELSE (* not executed *)
Int_Glob := 100;
Proc_7(10, Int_Glob, Pointer_Glob^.Int_Comp)
END;
PROCEDURE Proc_2 (VAR Int_Par_Ref: One_To_Fifty);
(***************)
(* executed once *)
(* In_Par_Ref = 3, becomes 7 *)
VAR
Int_Loc: One_To_Fifty;
Enum_Loc: Enumeration;
BEGIN
Int_Loc := Int_Par_Ref + 10;
REPEAT (* executed once *)
IF Char_Glob_1 = 'A' THEN
BEGIN (* executed *)
Int_Loc := Int_Loc - 1;
Int_Par_Ref := Int_Loc - Int_Glob;
Enum_Loc := Ident_1
END (* if *)
UNTIL Enum_Loc = Ident_1 (* true *)
END;
PROCEDURE Proc_1 (Pointer_Par_Val: Record_Pointer);
(**************)
(* executed once *)
BEGIN
WITH Pointer_Par_Val^ DO
BEGIN
Pointer_Comp^ := Pointer_Glob^;
Pointer_Par_Val^.Int_Comp := 5;
Pointer_Comp^.Int_Comp := Pointer_Par_Val^.Int_Comp;
Pointer_Comp^.Pointer_Comp := Pointer_Par_Val^.Pointer_Comp;
Proc_3(Pointer_Comp^.Pointer_Comp);
(* Pointer_Par_Val^.Pointer_Comp^.Pointer_Comp
= Pointer_Glob^.Pointer_Comp *)
IF Pointer_Comp^.Discr = Ident_1 THEN
BEGIN (* executed *)
Pointer_Comp^.Int_Comp := 6;
Proc_6(Pointer_Par_Val^.Enum_Comp, Pointer_Comp^.Enum_Comp);
Pointer_Comp^.Pointer_Comp := Pointer_Glob^.Pointer_Comp;
Proc_7(Pointer_Comp^.Int_Comp, 10, Pointer_Comp^.Int_Comp)
END ELSE (* not executed *)
Pointer_Par_Val^ := Pointer_Comp^;
END
END;
PROCEDURE Proc_0;
(**************)
VAR
Int_Loc_1,
Int_Loc_2,
Int_Loc_3 : One_To_Fifty;
Char_Index: CHAR;
Enum_Loc: Enumeration;
String_Loc_1,
String_Loc_2: Str30;
Iter : BmInt;
BEGIN
(* Initializations *)
NEW(Next_Pointer_Glob);
NEW(Pointer_Glob);
WITH Pointer_Glob^ DO
BEGIN
Pointer_Comp := Next_Pointer_Glob;
Discr := Ident_1;
Enum_Comp := Ident_3;
Int_Comp := 40;
String_Comp := 'DHRYSTONE PROGRAM, SOME STRING'
END;
Array_Glob_2[8][7] := 10;
String_Loc_1 := 'DHRYSTONE PROGRAM, 1`ST STRING';
(******************************************************************************)
(* Compute the looping overhead. The Dummy procedure must have some side- *)
(* effect so that it is not optimised out of existence. *)
(******************************************************************************)
StartTimer; (* Start the clock. *)
REPEAT
Dummy;
UNTIL NullTimesUp;
(******************************************************************************)
(* Now run the benchmark. Note that the Dummy procedure is also called so *)
(* that we can eliminate its overhead from the looping overhead. *)
(******************************************************************************)
StartTimer; (* Start the clock. *)
REPEAT
Proc_5;
Proc_4;
(* Char_Glob_1 = 'A', Char_Glob_2 = 'B', Bool_Glob = FALSE *)
Int_Loc_1 := 2;
Int_Loc_2 := 3;
String_Loc_2 := 'DHRYSTONE PROGRAM, 2`ND STRING';
Enum_Loc := Ident_2;
Bool_Glob := NOT Func_2(String_Loc_1, String_Loc_2);
(* Bool_Glob = TRUE *)
WHILE Int_Loc_1 < Int_Loc_2 DO (* loop body executed once *)
BEGIN
Int_Loc_3 := 5 * Int_Loc_1 - Int_Loc_2;
(* Int_Loc_3 == 7 *)
Proc_7 (Int_Loc_1, Int_Loc_2, Int_Loc_3);
(* Int_Loc_3 == 7 *)
Int_Loc_1 := Int_Loc_1 + 1;
END; (* while *)
(* Int_Loc_1 = 3 *)
Proc_8 (Array_Glob_1, Array_Glob_2, Int_Loc_1, Int_Loc_3);
(* Int_Glob == 5 *)
Proc_1 (Pointer_Glob);
FOR Char_Index := 'A' TO Char_Glob_2 DO (* loop body executed twice *)
IF Enum_Loc = Func_1 (Char_Index, 'C')
THEN (* not executed *)
Proc_6 (Ident_1, Enum_Loc);
(* Int_Loc_1 = 3, Int_Loc_2 = 3, Int_Loc_3 = 7 *)
Int_Loc_3 := Int_Loc_2 * Int_Loc_1;
Int_Loc_2 := Int_Loc_3 DIV Int_Loc_1;
Int_Loc_2 := 7 * (Int_Loc_3 - Int_Loc_2) - Int_Loc_1;
Proc_2 (Int_Loc_1);
Dummy
UNTIL BenchTimesUp;
END;
BEGIN
WriteLn;
WriteLn('Dhrystone Benchmark (March 84), Version Pascal / 2');
WriteLn('All times are CPU times, in seconds');
Proc_0;
ReportTimes;
END.